﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data;
using WordService.Model;

namespace WordService.Utility
{
    public class MatrixUtil
    {

        /// <summary>
        /// 基础矩阵的处理方法
        /// </summary>
        /// <param name="_MatrixMap">传入的是键值对应的模型</param>
        /// <returns></returns>
        public static DataTable CalculateMatrix(IList<Keyword> _OrgKeywordList,Boolean isRate)
        {
            DataTable resultMatrix = new DataTable();
            if (_OrgKeywordList != null && _OrgKeywordList.Count > 0)
            {
                // 生成矩阵头部
                DataColumn column = new DataColumn();
                column.ColumnName = "关键字矩阵";
                resultMatrix.Columns.Add(column);
                Hashtable matrix = GetMatrix(_OrgKeywordList);
                foreach (String key in matrix.Keys)
                {
                    column = new DataColumn(key);
                    resultMatrix.Columns.Add(column);
                }
                // 生成每一行的数据
                foreach (String key in matrix.Keys)
                {
                    /// 生成行数据
                    DataRow row = resultMatrix.NewRow();
                    /// 第一列的设置
                    row["关键字矩阵"] = key;
                    /// 当前行的数据
                    foreach (String innerKey in matrix.Keys)
                    {
                        /// 计算当前某个单元格的数据
                        Decimal result = CalculateCell(key, innerKey, matrix, isRate);
                        if (innerKey != null && !innerKey.Equals(String.Empty))
                        {
                            row[innerKey] = result;
                        }
                    }
                    resultMatrix.Rows.Add(row);
                }
            }
            return resultMatrix;
        }

        private static Decimal CalculateCell(String cKey, String rKey, Hashtable matrix, Boolean isRate)
        {
            Decimal result = new Decimal();
            if (cKey.Trim().Equals(rKey))
            {
                Hashtable innerMatrix = (Hashtable)matrix[cKey];
                foreach (Keyword keyword in innerMatrix.Values)
                {
                    if (keyword != null)
                    {
                        if (isRate)
                        {
                            result += Convert.ToDecimal(keyword.RightRate * keyword.RightRate);
                        }
                        else
                        {
                            result += 1;
                        }
                    }
                }
            }
            else
            {
                Hashtable columnMatrix = (Hashtable)matrix[cKey];
                Hashtable rowMatrix = (Hashtable)matrix[rKey];
                foreach (Keyword cKeyword in columnMatrix.Values)
                {
                    Int64 id = cKeyword.Article.ID;
                    foreach (Keyword rKeyword in rowMatrix.Values)
                    {
                        if (rKeyword.Article.ID == id)
                        {
                            if (isRate)
                            {
                                result += Convert.ToDecimal(cKeyword.RightRate * rKeyword.RightRate);
                            }
                            else
                            {
                                result += 1;
                            }
                        }
                    }
                }
            }
            return result;
        }

        private static Hashtable GetMatrix(IList<Keyword> keywords)
        {
            Hashtable matrix = new Hashtable();
            foreach (Keyword keyword in keywords)
            {
                Hashtable innerMatrix = new Hashtable();
                // 一级的Hashtable
                if (matrix.ContainsKey(keyword.Name))
                {
                    innerMatrix = (Hashtable)matrix[keyword.Name];
                    matrix.Remove(keyword.Name);
                }
                else
                {
                    innerMatrix = new Hashtable();
                }
                innerMatrix.Add(keyword.ID, keyword);
                matrix.Add(keyword.Name, innerMatrix);
            }
            return matrix;
        }
        /// <summary>
        /// 作者基础矩阵的处理方法
        /// </summary>
        /// <param name="_OrgAuthorList"></param>
        /// <param name="isRate"></param>
        /// <returns></returns>
        public static DataTable CalculateMatrix(IList<Author> _OrgAuthorList, Boolean isRate)
        {
            DataTable resultMatrix = new DataTable();
            if (_OrgAuthorList != null && _OrgAuthorList.Count > 0)
            {
                //生成矩阵头部
                DataColumn column = new DataColumn();
                column.ColumnName = "作者矩阵";
                resultMatrix.Columns.Add(column);
                Hashtable matrix = GetMatrix(_OrgAuthorList);
                foreach(String key in matrix.Keys)
                {
                    column = new DataColumn(key);
                    resultMatrix.Columns.Add(column);
                }
                //生成每一行的数据
                foreach (String key in matrix.Keys)
                {
                    /// 生成行数据
                    DataRow row = resultMatrix.NewRow();
                    /// 第一列的设置
                    row["作者矩阵"] = key;
                    /// 当前行的数据
                    foreach (String innerKey in matrix.Keys)
                    {
                        /// 计算当前某个单元格的数据
                        Decimal result = CalculateCellAuthor(key, innerKey, matrix, isRate);
                        if (innerKey != null && !innerKey.Equals(String.Empty))
                        {
                            row[innerKey] = result;
                        }
                    }
                    resultMatrix.Rows.Add(row);
                }
            }
            return resultMatrix;
        }
        private static Decimal CalculateCellAuthor(String rKey, String cKey, Hashtable matrix, Boolean isRate)
        {
            Decimal result = new Decimal();
            if (rKey.Trim().Equals(cKey))
            {
                Hashtable innerMatrix = (Hashtable)matrix[rKey];
                foreach (Author author in innerMatrix.Values)
                {
                    if (author != null)
                    {
                        if (isRate)
                        {
                            result += Convert.ToDecimal(author.RightRate * author.RightRate);
                        }
                        else
                        {
                            result += 1;
                        }
                    }
                }
            }
            else
            {
                Hashtable rowMatrix = (Hashtable)matrix[rKey];
                Hashtable columnMatrix = (Hashtable)matrix[cKey];
                foreach (Author rAuthor in rowMatrix.Values)
                {
                    Int64 id = rAuthor.Article.ID;
                    foreach (Author cAuthor in columnMatrix.Values)
                    {
                        if (cAuthor.Article.ID == id)
                        {
                            if (isRate)
                            {
                                result += Convert.ToDecimal(rAuthor.RightRate * cAuthor.RightRate);
                            }
                            else
                            {
                                result += 1;
                            }
                        }
                    }
                }
            }
            return result;
        }
        private static Hashtable GetMatrix(IList<Author> authors)
        {
            Hashtable matrix = new Hashtable();
            foreach(Author author in authors)
            {
                Hashtable innerMatrix = new Hashtable();
                // 二级的Hashtable
                if (matrix.ContainsKey(author.Name))
                {
                    innerMatrix = (Hashtable)matrix[author.Name];
                    matrix.Remove(author.Name);
                }
                else
                {
                    innerMatrix = new Hashtable();
                }
                innerMatrix.Add(author.ID, author);
                matrix.Add(author.Name,innerMatrix);
            }
            return matrix;
        }
        /// <summary>
        /// 机构基础矩阵的处理方法
        /// </summary>
        /// <param name="_OrgInstitutionList"></param>
        /// <returns></returns>
        public static DataTable CalculateMatrix(IList<Institution> _OrgInstitutionList)
        {
            DataTable resultMatrix = new DataTable();
            if (_OrgInstitutionList != null && _OrgInstitutionList.Count > 0)
            {
                //生成矩阵头部
                DataColumn column = new DataColumn();
                column.ColumnName = "机构矩阵";
                resultMatrix.Columns.Add(column);
                Hashtable matrix = GetMatrix(_OrgInstitutionList);
                foreach (String key in matrix.Keys)
                {
                    column = new DataColumn(key);
                    resultMatrix.Columns.Add(column);
                }
                //生成每一行的数据
                foreach (String key in matrix.Keys)
                {
                    /// 生成行数据
                    DataRow row = resultMatrix.NewRow();
                    /// 第一列的设置
                    row["机构矩阵"] = key;
                    /// 当前行的数据
                    foreach (String innerKey in matrix.Keys)
                    {
                        /// 计算当前某个单元格的数据
                        Decimal result = CalculateCell(key, innerKey, matrix);
                        if (innerKey != null && !innerKey.Equals(String.Empty))
                        {
                            row[innerKey] = result;
                        }
                    }
                    resultMatrix.Rows.Add(row);
                }
            }
            return resultMatrix;
        }
        private static Hashtable GetMatrix(IList<Institution> institutions)
        {
            Hashtable matrix = new Hashtable();
            foreach (Institution institution in institutions)
            {
                Hashtable innerMatrix = new Hashtable();
                // 二级的Hashtable
                if (matrix.ContainsKey(institution.Name))
                {
                    innerMatrix = (Hashtable)matrix[institution.Name];
                    matrix.Remove(institution.Name);
                }
                else
                {
                    innerMatrix = new Hashtable();
                }
                innerMatrix.Add(institution.ID, institution);
                matrix.Add(institution.Name, innerMatrix);
            }
            return matrix;
        }
        private static Decimal CalculateCell(String rKey, String cKey, Hashtable matrix)
        {
            Decimal result = new Decimal();
            if (rKey.Trim().Equals(cKey))
            {
                Hashtable innerMatrix = (Hashtable)matrix[rKey];
                foreach(Institution institution in innerMatrix.Values)
                {
                    if (institution != null)
                    {
                        result += 1;
                    }
                }
            }
            else
            {
                Hashtable rowMatrix = (Hashtable)matrix[rKey];
                Hashtable columnMatrix = (Hashtable)matrix[cKey];
                foreach (Institution rInstitution in rowMatrix.Values)
                {
                    Int64 id = rInstitution.Article.ID;
                    foreach (Institution cInstitution in columnMatrix.Values)
                    {
                        if (cInstitution.Article.ID == id)
                        {
                            result += 1;
                        }
                    }
                }
            }
            return result;
        }
    }
}
